#
# Special tags used by the blog app.
#
import calendar

from django import template

from kangapy4.blog import common

register = template.Library()

@register.filter
def english_list(lst):
    """ Render as a list of English words.
    """
    if len(lst) == 0:
        return '-'

    if len(lst) == 1:
        return lst[0]

    return '%s and %s' % (', '.join(lst[:-1]), lst[-1])

@register.simple_tag
def month_archive_url(month, category):
    return common.make_month_archive_url(month, category)


@register.tag
def render_calendar(parser, token):
    if len(token.split_contents()) != 1:
        raise template.TemplateSyntaxError, \
                "%r tag should not have arguments" % token.contents[0]
    return CalendarNode()

class CalendarNode(template.Node):
    def __init__(self):
        self.output = ''

    def render(self, context):
        self.cal = context['calendar']
        self.output += '<table>'
        self.render_header()
        self.render_dates()
        self.output += '</table>'
        return self.output

    def render_dates(self):
        m = self.cal.month
        rawcal = calendar.monthcalendar(m.year, m.month)
        for week in rawcal:
            self.output += '<tr>'
            for day in week:
                if day == 0:
                    self.output +=  """<td class="notaday"></td>"""
                elif self.cal.has_entry_on_day(day):
                    self.output += """<td class="linkday">""" \
                        """<a href="%s">%d</a></td>""" \
                        % (self.cal.get_day_url(day), day)
                else:
                    self.output +=  """<td class="day">%d</td>""" % day
            self.output += '</tr>'
        
    def render_header(self):
        self.output += '<tr>'
        for d in range(7):
            name = calendar.day_abbr[(d + calendar.firstweekday()) % 7] 
            self.output += "<th>%s</th>" % name[0]
        self.output += '</tr>'


@register.tag
def with(parser, token):
    """ Alias an expression. Useful for parameterising templates.
        Format is: {% with alias = expression %}
    """
    bits = token.contents.split()
    msg = "'with' statements should be of the form 'with alias = expression: %s'" \
            % token.contents
    if len(bits) != 4 or bits[2] != '=':
        raise template.TemplateSyntaxError, msg
    alias = bits[1]
    expr = parser.compile_filter(bits[3])
    nodelist = parser.parse(('endwith',))
    parser.delete_first_token()
    return WithNode(alias, expr, nodelist)

class WithNode(template.Node):
    """ Handles 'with' tags.
    """
    def __init__(self, alias, expr, nodelist):
        self.alias = alias
        self.expr = expr
        self.nodelist = nodelist 

    def __iter__(self):
        for node in self.nodelist:
            yield node

    def get_nodes_by_type(self, nodetype):
        """ Return a list of all nodes (within this node and its nodelist) 
            of the given type
        """
        nodes = []
        if isinstance(self, nodetype):
            nodes.append(self)
        nodes.extend(self.nodelist.get_nodes_by_type(nodetype))
        return nodes

    def render(self, context):
        """ Render the contents of the with block, using the new variable 
            value.
        """
        result = template.NodeList()
        context.push()
        context[self.alias] = self.expr.resolve(context)

        for node in self.nodelist:
            result.append(node.render(context))

        context.pop()
        return result.render(context)
